package reflect;


import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import package1.Test;

import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class ReflectTest {

    public static void main(String[] args) {
        //fun(CommonUtils.class);
        List<String> list = fun2(Map.class);
        for (String s : list) {
            System.out.println(s);
        }
    }

    //private static void fun(Class<?> clazz) {
    //    System.out.println(clazz.getName());
    //    // 1. 获取当前类中声明的方法
    //    Method[] declaredMethods = clazz.getDeclaredMethods();
    //    LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
    //    // 2. 遍历得到的方法
    //    for (Method declaredMethod : declaredMethods) {
    //
    //        // 3. 判断当前遍历到的方法是否为 public static 修饰符修饰的方法
    //        //boolean aStatic = Modifier.isStatic(declaredMethod.getModifiers());
    //        //boolean aPublic = Modifier.isPublic(declaredMethod.getModifiers());
    //        //System.out.println(declaredMethod.getName() + "是静态方法吗?" + aStatic);
    //        //System.out.println(declaredMethod.getName() + "是公共方法吗？" + aPublic);
    //        // 4. 获取当前方法的方法名称
    //        String methodName = declaredMethod.getName();
    //        System.out.println("methodName = " + methodName);
    //        // 5. 获取当前方法的返回值类型
    //        //Type returnType = declaredMethod.getReturnType();
    //        //System.out.println("returnType = " + returnType);
    //        //System.out.println("returnType.getTypeName() = " + returnType.getTypeName());
    //        //// 6. 获取当前方法带泛型的返回值类型
    //        Type genericReturnType = declaredMethod.getGenericReturnType();
    //        //System.out.println("genericReturnType = " + genericReturnType);
    //        System.out.println("genericReturnType.getTypeName() = " + genericReturnType.getTypeName());
    //
    //        // 7. 获取当前方法的返回值的泛型类型
    //        //if (genericReturnType instanceof ParameterizedType) {
    //        //    ParameterizedType parameterizedType = (ParameterizedType) genericReturnType;
    //        //    Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
    //        //    for (Type actualTypeArgument : actualTypeArguments) {
    //        //        String typeName = actualTypeArgument.getTypeName();
    //        //        System.out.println("typeName* = " + typeName);
    //        //    }
    //        //}
    //        // 8. 获取当前方法的参数名称和参数类型
    //        Type[] genericParameterTypes = declaredMethod.getGenericParameterTypes();
    //        // 获取参数名称
    //        String[] parameterNames = discoverer.getParameterNames(declaredMethod);
    //        if(parameterNames != null){
    //            Type[] genericParameterTypes2 = declaredMethod.getGenericParameterTypes();
    //            for(int i=0;i<parameterNames.length;i++){
    //                System.out.println("parameterName = " + parameterNames[i]+"::"+genericParameterTypes2[i].getTypeName());
    //            }
    //            //for (String parameterName : parameterNames) {
    //            //    System.out.println("parameterName = " + parameterName);
    //            //    Type[] genericParameterTypes1 = declaredMethod.getGenericParameterTypes();
    //            //    System.out.println(genericParameterTypes1[0].getTypeName());
    //            //}
    //        }
    //        //for (Type genericParameterType : genericParameterTypes) {
    //            //if (genericParameterType instanceof ParameterizedType) {
    //            //    System.out.println("**"+genericParameterType.getTypeName());
    //            //    ParameterizedType parameterizedType = (ParameterizedType) genericParameterType;
    //            //    Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
    //            //    for (Type actualTypeArgument : actualTypeArguments) {
    //            //        System.out.println("actualTypeArgument = " + actualTypeArgument.getTypeName());
    //            //    }
    //            //}else {
    //            //    System.out.println(genericParameterType.getTypeName());
    //            //}
    //            //System.out.println("**"+genericParameterType.getTypeName());
    //        //}
    //        System.out.println("----");
    //
    //    }
    //}


    private static List<String> fun2(Class<?> clazz) {
        List<String> list = new ArrayList<>();
        StringBuilder stringBuilder = new StringBuilder();
        // 1. 获取当前类中声明的方法
        Method[] declaredMethods = clazz.getDeclaredMethods();

        LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
        // 2. 遍历得到的方法
        for (Method declaredMethod : declaredMethods) {
            // 6. 获取当前方法的返回值类型
            Type genericReturnType = declaredMethod.getGenericReturnType();
            stringBuilder.append(genericReturnType.getTypeName()+" "); // 拼接方法的返回值类型

            // 4. 获取当前方法的方法名称
            String methodName = declaredMethod.getName();
            stringBuilder.append(methodName+"(");   // 拼接方法的名称

            // 8. 获取当前方法的参数名称和参数类型
            Parameter[] parameters = declaredMethod.getParameters();

            if (parameters != null && parameters.length>0) {
                Type[] genericParameterTypes2 = declaredMethod.getGenericParameterTypes();
                for (int i = 0; i < parameters.length; i++) {
                    if(i < parameters.length-1){
                        stringBuilder.append(genericParameterTypes2[i].getTypeName()+","); // 拼接方法的参数类型
                    }else {
                        stringBuilder.append(genericParameterTypes2[i].getTypeName()+")");
                    }
                }
            }else {
                stringBuilder.append(")");
            }
            list.add(stringBuilder.toString());
            stringBuilder.delete(0,stringBuilder.length());
        }
        return list;
    }

    private static void fun1(Class<?> clazz) {
        // 0. 获取函数所在的类名
        System.out.println("类名：" + clazz.getName());
        // 1. 获取当前类中声明的方法
        Method[] declaredMethods = clazz.getDeclaredMethods();
        LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
        // 2. 遍历得到的方法
        for (Method declaredMethod : declaredMethods) {
            // 4. 获取当前方法的方法名称
            String methodName = declaredMethod.getName();
            System.out.println("方法名称：" + methodName);
            // 6. 获取当前方法的返回值类型
            Type genericReturnType = declaredMethod.getGenericReturnType();
            System.out.println("方法的返回值类型：" + genericReturnType.getTypeName());

            Parameter[] parameters = declaredMethod.getParameters();
            // 8. 获取当前方法的参数名称和参数类型
            String[] parameterNames = discoverer.getParameterNames(declaredMethod);
            if (parameters != null) {
                Type[] genericParameterTypes2 = declaredMethod.getGenericParameterTypes();
                for (int i = 0; i < parameters.length; i++) {
                    System.out.println("参数名称：" + parameters[i] + "，参数类型：" + genericParameterTypes2[i].getTypeName());
                }
            }
            System.out.println("----");
        }
    }
}
